package main

import (
	"math/big"
	"strings"
	"unicode"
)

var unordered_map = map[string][]string{
	"start":     {"start", "signed", "in_number", "end"},
	"signed":    {"end", "end", "in_number", "end"},
	"in_number": {"end", "end", "in_number", "end"},
	"end":       {"end", "end", "end", "end"},
}
var state = "start"

func get_col(s rune) int {
	if string(s) == " " {
		return 0
	} else if string(s) == "+" || string(s) == "-" {
		return 1
	} else if unicode.IsDigit(s) {
		return 2
	}
	return 3
}

var sign = 1

var ans = big.NewInt(0)

const MIN int64 = -2147483648
const MAX int64 = 2147483647

func get(s rune) {
	state = unordered_map[state][get_col(s)]
	if state == "in_number" {
		ans.Mul(ans, big.NewInt(10))
		ans.Add(ans, big.NewInt(int64(s-'0')))
		if sign == 1 {
			ans = Max(*ans)
		} else {
			ans = Min(*ans)
		}
	} else if state == "signed" {
		if s == '+' {
			sign = 1
		} else {
			sign = -1
		}
	}
}

func Max(a big.Int) *big.Int {
	if a.Cmp(big.NewInt(MAX)) > 0 {
		return big.NewInt(MAX)
	}
	return &a
}

func Min(a big.Int) *big.Int {
	if ans.Cmp(big.NewInt(MIN)) < 0 {
		return big.NewInt(MIN)
	}
	return &a
}

func myAtoi(s string) int {
	//去除首尾字符
	s = strings.TrimSpace(s)
	if len(s) == 0 {
		return 0
	}
	for _, str := range s {
		get(str)
	}
	return sign * int(ans.Int64())
}

func main() {
	print(myAtoi("   -42"))
}
